package com.library.uiframework.Immersive;

import java.util.ArrayList;

import android.annotation.TargetApi;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;

/**
 * @author h.z
 * @version 1.0.0
 * @since 2015/1/29.
 */
public class ImmersiveObserver {

    private final ArrayList<View> mTopViewList = new ArrayList<>();
    private final ArrayList<View> mBottomViewList = new ArrayList<>();

    private View mObserverView;
    private ImmersiveOnApplyStyleListener mOnApplyStyleListener;
    private ImmersiveOnApplyPaddingListener mOnApplyPaddingListener;
    private View.OnLayoutChangeListener mOnLayoutChangeListener;
    /**
     *
     * @param observerView view
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public ImmersiveObserver(View observerView) {
        if (observerView != null) {
            mOnLayoutChangeListener = new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View v, int left, int top, int right, int bottom
                        , int oldLeft, int oldTop, int oldRight, int oldBottom) {
                    doInject(v, true);
                }
            };
            observerView.addOnLayoutChangeListener(mOnLayoutChangeListener);
        }
        mObserverView = observerView;
    }

    /**
     *
     * @param topView top view which has status bar padding
     * @param bottomView bottom view which should have navigation bar padding
     * @param topMaskView top view mask
     * @param bottomMaskView bottom view mask
     */
    public void setImmersiveView(View topView, View bottomView, View topMaskView, View bottomMaskView) {

        clearImmersiveView();

        mTopViewList.add(topView);
        mTopViewList.add(topMaskView);

        mBottomViewList.add(bottomView);
        mBottomViewList.add(bottomMaskView);
    }

    /**
     * 增加一组immersive view控制
     * @param topView top view
     */
    public void addImmersiveTopView(View topView) {
        if (topView != null) {
            mTopViewList.add(topView);
        }
    }

    /**
     *
     * @param bottomView bottom view
     */
    public void addImmersiveBottomView(View bottomView) {
        if (bottomView != null) {
            mBottomViewList.add(bottomView);
        }
    }

    /**
     * 清除 immersive view控制
     */
    public void clearImmersiveView() {
        clearImmersiveTopView();
        clearImmersiveBottomView();
    }

    /**
     *
     */
    public void clearImmersiveTopView() {
        mTopViewList.clear();
    }

    /**
     *
     */
    public void clearImmersiveBottomView() {
        mBottomViewList.clear();
    }

    /**
     * 应用沉浸模式，调整影响到的view
     */
    public void apply() {
        doInject(mObserverView, true);
    }

    private void doInject(View view, boolean onLayoutChange) {
        if (view == null) {
            return;
        }
        int paddingTop = view.getPaddingTop();
        int paddingBottom = view.getPaddingBottom();

        if (onLayoutChange || mOnApplyStyleListener != null) {
            int usePaddingTop = (mOnApplyStyleListener == null || mOnApplyStyleListener.needApplyStatusBarStyle()) ? paddingTop : 0;
            for (View topView : mTopViewList) {
                setPaddingTop(topView, usePaddingTop);
            }

            int usePaddingBottom = (mOnApplyStyleListener == null || mOnApplyStyleListener.needApplyNavigationBarStyle()) ? paddingBottom : 0;
            for (View bottomView : mBottomViewList) {
                setPaddingBottom(bottomView, usePaddingBottom);
            }
        }
    }

    private void setPaddingTop(View view, int paddingTop) {
        if (view != null && view.getPaddingTop() != paddingTop) {
            int dPaddingTop = paddingTop - view.getPaddingTop();
            view.setPadding(view.getPaddingLeft(), paddingTop, view.getPaddingRight(), view.getPaddingBottom());
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            if (layoutParams != null && layoutParams.height >= 0) {
                layoutParams.height += dPaddingTop;
                view.setLayoutParams(layoutParams);
            }
            if (mOnApplyPaddingListener != null) {
                mOnApplyPaddingListener.onAppliedTopPadding(view, paddingTop);
            }
        }
    }

    private void setPaddingBottom(final View view, int paddingBottom) {
        if (view != null && view.getPaddingBottom() != paddingBottom) {
            int dPaddingBottom = paddingBottom - view.getPaddingBottom();
            view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), paddingBottom);
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            if (layoutParams != null && layoutParams.height >= 0) {
                layoutParams.height += dPaddingBottom;
                view.setLayoutParams(layoutParams);
            }
            // 不知道为什么，设置padding后，需要手动调用requestLayout才能正确布局
            view.post(new Runnable() {
                @Override
                public void run() {
                    view.requestLayout();
                }
            });
            if (mOnApplyPaddingListener != null) {
                mOnApplyPaddingListener.onAppliedBottomPadding(view, paddingBottom);
            }
        }
    }

    /**
     *
     * @param styleListener listener
     */
    public void setOnApplyStyleListener(ImmersiveOnApplyStyleListener styleListener) {
        mOnApplyStyleListener = styleListener;
    }

    /**
     *
     * @param listener listener
     */
    public void setOnApplyPaddingListener(ImmersiveOnApplyPaddingListener listener) {
        mOnApplyPaddingListener = listener;
    }


    /**
     * removeOnLayoutChangeListener
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void removeOnLayoutChangeListener() {
        if (mObserverView != null) {
            mObserverView.removeOnLayoutChangeListener(mOnLayoutChangeListener);
        }
    }
}
